import { director, instantiate, Pool, Prefab, randomRangeInt, resources, Node, Animation, SkeletalAnimationState } from "cc";
import { Actor } from "../actor/Actor";
import { Events } from "../events/Events";
import { StateDefine } from "../actor/StateDefine";
import { EffectManager } from '../level/EffectManager';
import { ResourceDefine } from "../resource/ResourceDefine";

// 全局 actor 管理器
export class ActorManager  {
    
   private static _instance: ActorManager;
   static get instance():ActorManager{
    if(this._instance == null){
        this._instance = new ActorManager();
    }
    return this._instance;
   }


    // 主角
    playActor:Actor = null;

    // 敌人
    enemies:Array<Node> = [];

    // 敌人角色内存池
    enemypool: Pool<Node> = null;

    init(onComplete:() => void){
        resources.loadDir("Actor/Enemy", Prefab, (err: Error, prefabs: Prefab[])=>{
            
            if(err)
            {
                throw err;
            }

            this.enemypool = new Pool<Node>(
                (): Node => {
                    let prefab = prefabs[randomRangeInt(0, prefabs.length)];
                    let node = instantiate(prefab);
                    director.getScene().addChild(node);
                    return node;
                }, 10 * prefabs.length, 
                (node: Node) => {
                    node.removeFromParent();
                }
            )

            onComplete();
        })

    }

    destroy(){
        this.enemypool.destroy();
        this.enemies = [];
    }


    createEnemy():Node {
        let node = this.enemypool.alloc();
        node.active = true;
        this.enemies.push(node);
        node.on(Events.OnDie, this.onOnEnemyDie, this);
        return node;
    }

    onOnEnemyDie(node:Node){
        const index = this.enemies.indexOf(node);
        // 监听角色死亡动画事件，播放完毕销毁
        this.enemies.splice(index, 1);
        let actor = node.getComponent(Actor);
        // 监听动画完成事件，如果当前是死亡动画完成，就销毁角色
        actor.skeletalAnimation.on(Animation.EventType.FINISHED,
            (type: Animation.EventType, state: SkeletalAnimationState)=>{
            if(state.name == StateDefine.Die){
                this.enemypool.free(node);
                node.active = false;
            }
            // 死亡动画
            EffectManager.instance.play(ResourceDefine.EffDie, node.worldPosition);

        })
     
    }
    

    get randomEnemy():Node{
        return this.enemies[randomRangeInt(0, this.enemies.length)];
    }
}

